﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Kitware.VTK;


namespace HAVTKPack
{
    public class HydrolicSourceSinksGeometry : Geometry
    {


       #region 构造函数  目前使用的第三个构造函数

        public HydrolicSourceSinksGeometry(HydrolicGrid hg)
        {
            this._hg = hg;
        }

        public HydrolicSourceSinksGeometry(HydrolicGrid hg, List<int[,]> effectiveCellSign)
        {

            this._hg = hg;
            this.EffectiveSign1 = effectiveCellSign;
        }


        public HydrolicSourceSinksGeometry(HydrolicGrid hg, List<int[,]> effectiveCellSign, List<int[]> newijks)
        {

            this._hg = hg;
            this.EffectiveSign1 = effectiveCellSign;
            this.ijkindexs = newijks;


        }


        #endregion

        #region 字段属性

        HydrolicGrid _hg;
        /// <summary>
        /// 不规则网格数据源
        /// </summary>
        public HydrolicGrid Hg
        {
            get { return _hg; }
            set
            {

                _hg = value;
                this.OnHydrollicGridChanged();
            }
        }


        List<int[,]> EffectiveSign;
        /// <summary>
        /// 单元的有效性标记数组
        /// </summary>
        public List<int[,]> EffectiveSign1
        {
            get { return EffectiveSign; }
            set
            {

                EffectiveSign = value;
                this.OnEffectiveSign1Changed();

            }
        }

        List<int[]> ijkindexs ; 
        //List<int[]> ijkindexs = new List<int[]>();
        /// <summary>
        /// 标记哪个单元格需要添加Well标志
        /// 其中的一维数组中应该有4位  i，j，k，index （i为网格的row，j为网格col，k为网格layer，index为点的id值，所有的从1开始）
        /// </summary>
        public  List<int[]> Ijkindexs
        {
            get { return ijkindexs; }
            set
            {
                ijkindexs = value;
                this.OnIjkindexSignChanged();
            }
        }



        //Vector scaleVector = new Vector(1, 1, 1);




        #endregion




        #region VTK流水线所需要的对象

        vtkUnstructuredGrid unGrid;
        vtkPolyVertex aPolyVertex;



        //vtkTransform _transform;
        //public vtkTransform Transform
        //{
        //    get { return _transform; }
        //    set { _transform = value; }
        //}

        vtkTransformFilter _transFormFilter;


        #endregion

        public override void Render()
        {

            unGrid = vtkUnstructuredGrid.New();

            //if (this.aPolyVertex==null )
            //{
            aPolyVertex = vtkPolyVertex.New();
            //}


            this.GetPointsAndCellArray();

            if (this.GeometryTransform ==null )
            {
                this.GeometryTransform = vtkTransform.New();
            }

            this.GeometryTransform.Identity();
            if (this.ParentNode !=null )
            {
                this.GeometryTransform.Scale(this.ParentNode.Scale.X, this.ParentNode.Scale.Y, this.ParentNode.Scale.Z);

                
            }
          
            //_transform = vtkTransform.New();

            _transFormFilter = vtkTransformFilter.New();
            _transFormFilter.SetTransform(this.GeometryTransform );
            //_transFormFilter.SetTransform(this._transform);
            _transFormFilter.SetInput(unGrid);

            //this._outPutData = this.unGrid;
            this._outPutData = this._transFormFilter.GetOutput();



            //throw new NotImplementedException();
        }

        public override void StopRender()
        {

            if (this._transFormFilter != null)
            {
                this._transFormFilter.Dispose();
            }
            //if (this._transform != null)
            //{
            //    this._transform.Dispose();
            //}
            if (this.aPolyVertex != null)
            {
                this.aPolyVertex.Dispose();
            }
            if (this.unGrid != null)
            {
                this.unGrid.Dispose();
            }






            //throw new NotImplementedException();
        }



        #region 属性改变

        private void OnHydrollicGridChanged()
        {
            if (this._hg == null)
            {
                return;
            }

            //this.SetPointsArray();
            this.GetPointsAndCellArray();

        }

        private void OnEffectiveSign1Changed()
        {
            if (this.EffectiveSign == null)
            {
                return;
            }
   

            //this.SetEffectiveCellArray();
            this.GetPointsAndCellArray();

        }

        private void OnIjkindexSignChanged()
        {
            if (this.ijkindexs == null)
            {
                return;
            }

            //this.SetIJKIndexSign();
            this.GetPointsAndCellArray();

        }




        #endregion

        #region 公有方法


        //public void UpdateTransformScale(Vector newScaleVector)
        //{
        //    //if (newScaleVector == null)
        //    //{
        //    //    return;
        //    //}

        //    //if (this.scaleVector == null)
        //    //{
        //    //    this.scaleVector = new Vector(1, 1, 1);
        //    //}


        //    this.scaleVector.X = newScaleVector.X;
        //    this.scaleVector.Y = newScaleVector.Y;
        //    this.scaleVector.Z = newScaleVector.Z;


        //    if (this.GeometryTransform != null)
        //    {
        //        this.GeometryTransform.Identity();
        //        this.GeometryTransform.Scale(this.scaleVector.X, this.scaleVector.Y, this.scaleVector.Z);

        //    }




        //}

        #endregion



        #region 内部方法

        /// <summary>
        /// 得到点集和单元集  构造网格
        /// </summary>
        private void GetPointsAndCellArray()
        {
            if (this.unGrid == null)
            {
                return;
            }


            //this.SetPointAndCellArray();



            #region

            //vtkFloatArray sizes = vtkFloatArray.New();

            //sizes.SetNumberOfTuples(4);
            //sizes.SetNumberOfComponents(1);

            //sizes.InsertNextTuple4(0,10,10,10);//点信息


            //vtkPoints points = vtkPoints.New();
            //points.SetData(sizes);



            ////vtkVertex vertex = vtkVertex.New();
            ////vertex.GetPointIds().SetId (0,1);



            //vtkPolyVertex polyVertex = vtkPolyVertex.New();
            //polyVertex.GetPointIds().SetId(0,1);


            //vtkCellArray verts = vtkCellArray.New();
            //verts.InsertNextCell(polyVertex.GetPointIds());
            

            //vtkPolyData polyData = vtkPolyData.New();
            //polyData.SetPoints(points );
            //polyData.SetVerts(verts);

            #endregion




            #region

            int nLayer = this._hg.NLayers;
            int nCol = this._hg.NCols;
            int nRow = this._hg.NRows;
            int nPts = nLayer * nCol * nRow;


            int nPoints = 0;


            #region  构造网格数据集

            //首先确定有效点（对应网格体单元）的个数

            int length;
            int row;
            int col;
            int layer;
            int indexPoint;

            for (int i = 0; i < this.ijkindexs.Count; i++)
            {
                 length = this.ijkindexs[i].Length;//应该有4位  i，j，k，index

                 row = this.ijkindexs[i][0] - 1;
                 col = this.ijkindexs[i][1] - 1;
                 layer = this.ijkindexs[i][2] - 1;

                 indexPoint = this.ijkindexs[i][3] - 1;

                if (this.EffectiveSign1[layer][row, col] != 0)
                {
                    nPoints = nPoints + 1;
                }
            }

            #region vtkPoints


            vtkPolyVertex aPolyVer = vtkPolyVertex.New();


            aPolyVer.GetPointIds().SetNumberOfIds(nPoints);



            vtkFloatArray array = vtkFloatArray.New();

            array.SetNumberOfComponents(3);

            array.SetNumberOfTuples(nPoints);


            int m = 0;

            Coordinate coord;


            for (int i = 0; i < this.ijkindexs.Count; i++)
            {
                 length = this.ijkindexs[i].Length;//应该有4位  i，j，k，index

                 row = this.ijkindexs[i][0] - 1;
                 col = this.ijkindexs[i][1] - 1;
                 layer = this.ijkindexs[i][2] - 1;

                 indexPoint = this.ijkindexs[i][3];

                if (this.EffectiveSign1[layer][row, col] != 0)
                {

                    coord = this._hg.Coords[row, col, layer];

                    array.SetTuple3(m, coord.X, coord.Y, coord.Z);

                    aPolyVer.GetPointIds().SetId(m, m);

                    m++;


                }
            }



            vtkPoints pts = vtkPoints.New();
            pts.SetData(array);


            #endregion


            #endregion

            //unGrid.Allocate(1, 1);//主动要求分配内存  很容易破坏内存  安全隐患 。。。。。。。。。怎么解决？？待研究

            unGrid.SetPoints(pts);

            unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());

            //unGrid.SetCells(aPolyVertex.GetCellType(), aPolyVer);


            this.unGrid.Modified ();
            //this.unGrid.Update();




            #endregion



        }




        #region Point  Cell 和 IJK分别操作

        /// <summary>
        /// 单独改变设置Points的信息
        /// </summary>
        private void SetPointsArray()
        {

            if (this.unGrid == null)
            {
                return;
            }

            int nLayer = this._hg.NLayers;
            int nCol = this._hg.NCols;
            int nRow = this._hg.NRows;
            int nPts = nLayer * nCol * nRow;


            int nPoints = 0;


            #region  构造网格数据集


            #region vtkPoints



            vtkFloatArray array = vtkFloatArray.New();

            array.SetNumberOfComponents(3);

            int m = 0;

            Coordinate coord;

            for (int i = 0; i < this.ijkindexs.Count; i++)
            {
                int length = this.ijkindexs[i].Length;//应该有4位  i，j，k，index

                int row = this.ijkindexs[i][0] - 1;
                int col = this.ijkindexs[i][1] - 1;
                int layer = this.ijkindexs[i][2] - 1;

      

                if (this.EffectiveSign1[layer][row, col] != 0)
                {

                    nPoints = nPoints + 1;

                    coord = this._hg.Coords[row, col, layer];

                    array.InsertNextTuple4 (m, coord.X, coord.Y, coord.Z);

                    m++;


                }
            }

            //array.SetNumberOfTuples(nPoints);


            vtkPoints pts = vtkPoints.New();
            pts.SetData(array);


            #endregion


            #endregion

          

            unGrid.SetPoints(pts);

            this.unGrid.Update();





        }


        /// <summary>
        /// 单独改变设置有效单元Cell的信息
        /// </summary>
        private void SetEffectiveCellArray()
        {
            if (this.unGrid == null)
            {
                return;
            }


            int nLayer = this._hg.NLayers;
            int nCol = this._hg.NCols;
            int nRow = this._hg.NRows;
            int nPts = nLayer * nCol * nRow;


            int nPoints = 0;


            #region  构造网格数据集

         
            #region vtkPoints


            vtkPolyVertex aPolyVer = vtkPolyVertex.New();

            int m = 0;

            Coordinate coord;


            for (int i = 0; i < this.ijkindexs.Count; i++)
            {
                int length = this.ijkindexs[i].Length;//应该有4位  i，j，k，index

                int row = this.ijkindexs[i][0] - 1;
                int col = this.ijkindexs[i][1] - 1;
                int layer = this.ijkindexs[i][2] - 1;

                int indexPoint = this.ijkindexs[i][3];

                if (this.EffectiveSign1[layer][row, col] != 0)
                {

                    nPoints = nPoints + 1;

                    coord = this._hg.Coords[row, col, layer];

                    aPolyVer.GetPointIds().InsertId  (m, m);
                    //aPolyVer.GetPointIds().SetId(m, m);

                    m++;

                }
            }

            //aPolyVer.GetPointIds().SetNumberOfIds(nPoints);



            #endregion


            #endregion


            unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());

            this.unGrid.Update();



        }


        /// <summary>
        /// 单独改变设置IJK改变时
        /// </summary>
        private void SetIJKIndexSign()
        {
            if (this.unGrid == null)
            {
                return;
            }


            this.SetPointAndCellArray();

        
        }



        /// <summary>
        /// 同时改变Point 和 Cell
        /// 当执行Render的时候  调用该方法
        /// 因为如果分别执行Point和Cell的变化则会造成里面的For循环重复，效率急剧下降，故这种情况将两者和在一起调用，只需要执行一套For循环
        /// </summary>
        private void SetPointAndCellArray()
        {


            if (this.unGrid == null)
            {
                return;
            }


            int nLayer = this._hg.NLayers;
            int nCol = this._hg.NCols;
            int nRow = this._hg.NRows;
            int nPts = nLayer * nCol * nRow;


            int nPoints = 0;


            #region  构造网格数据集


            #region vtkPoints


            vtkPolyVertex aPolyVer = vtkPolyVertex.New();

            vtkFloatArray array = vtkFloatArray.New();

            array.SetNumberOfComponents(3);

            int m = 0;

            Coordinate coord;


            for (int i = 0; i < this.ijkindexs.Count; i++)
            {
                int length = this.ijkindexs[i].Length;//应该有4位  i，j，k，index

                int row = this.ijkindexs[i][0] - 1;
                int col = this.ijkindexs[i][1] - 1;
                int layer = this.ijkindexs[i][2] - 1;

                int indexPoint = this.ijkindexs[i][3];

                if (this.EffectiveSign1[layer][row, col] != 0)
                {

                    nPoints = nPoints + 1;

                    coord = this._hg.Coords[row, col, layer];

                    array.InsertNextTuple4 (m, coord.X, coord.Y, coord.Z);

                    aPolyVer.GetPointIds().InsertId (m, m);

                    m++;


                }
            }
            //aPolyVer.GetPointIds().SetNumberOfIds(nPoints);
            //array.SetNumberOfTuples(nPoints);


            vtkPoints pts = vtkPoints.New();
            pts.SetData(array);


            #endregion

            #endregion


            unGrid.SetPoints(pts);

            unGrid.InsertNextCell(aPolyVertex.GetCellType(), aPolyVer.GetPointIds());


            this.unGrid.Update();

        }


        #endregion




        #endregion


    }
}
